package lv.rtu.ditf.dc.hashmap.routines;

import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * 
 * @author Pāvels Koliškins, Edgars Matisāns
 *
 */
public class HashMapRoutines {
    public static <K, V extends Comparable<V>> List<K> sortByValueDesc(final Map<K, V> m) {
        List<K> keys = new ArrayList<K>();
        keys.addAll(m.keySet());
        Collections.sort(keys, new Comparator<K>() {
            public int compare(K o1, K o2) {
                V v1 = m.get(o1);
                V v2 = m.get(o2);
                if (v1 == null) {
                    return (v2 == null) ? 0 : 1;
                }
                else if (v1 instanceof Comparable) { 
                    return v2.compareTo(v1);
                }
                // Edgars: this branch is now dead because of generics requires value to be comparable
                else {
                    return 0;
                }
            }
        });
        return keys;
    }
    
    public static void mergeAndSum(final Map<String, Integer> resultMap, final Map<String, Integer> mapToMerge) {
    	for (String key : mapToMerge.keySet()) {
    		Integer sum = resultMap.get(key);
    		
    		if (sum == null)
    			sum = mapToMerge.get(key);
    		else
    			sum += mapToMerge.get(key);
    		
    		resultMap.put(key, sum);
    	}
    }

	public static void mergeAndCount(HashMap<String, Integer> resultMap, HashMap<String, Integer> mapToMerge) {
    	for (String key : mapToMerge.keySet()) {
    		Integer count = resultMap.get(key);
    		
    		if (count == null)
    			count = 1;
    		else
    			count++;
    		
    		resultMap.put(key, count);
    	}
	}
	
	public static void subtractAndCount(HashMap<String, Integer> resultMap, HashMap<String, Integer> mapToSubtract) {
    	for (String key : mapToSubtract.keySet()) {
    		Integer count = resultMap.get(key);
    		
    		if (count != null && count > 0)
    			count--;
    		
    		resultMap.put(key, count);
    	}
	}
}
